<template>
  <!-- 底图切换控件：通过切换 viewer.imageryLayers 的主图层实现 -->
  <div class="imagery-control">
    <el-dropdown @command="switchLayer" placement="top-start">
      <el-button size="small" type="primary">
        底图切换 <el-icon class="el-icon--right"><arrow-down /></el-icon>
      </el-button>
      <template #dropdown>
        <el-dropdown-menu>
          <el-dropdown-item
            v-for="item in imageryOptions"
            :key="item.name"
            :command="item"
            :disabled="item.loading"
          >
            {{ item.name }}
            <span v-if="item.loading">（加载中...）</span>
          </el-dropdown-item>
        </el-dropdown-menu>
      </template>
    </el-dropdown>
  </div>
</template>

<script setup>
// 底图切换控件组件
// - 职责：提供一个下拉菜单，用于切换 viewer.imageryLayers 的主图层
// - 用法：放在 CesiumViewer 的 #entities 插槽中，自动获取 viewer 实例并切换图层
import { inject, ref, onMounted, watch } from "vue";
import * as Cesium from "cesium";
import { ArrowDown } from "@element-plus/icons-vue";

// 常量：与 CesiumViewer 中的 provide key 保持一致
const CESIUM_VIEWER_KEY = "cesiumViewer";

// 注入 viewer
const injectedViewerRef = inject(CESIUM_VIEWER_KEY, null);

// 响应式变量：当前选中的底图选项
const currentLayer = ref(null);

// 响应式数组：支持的底图选项列表
const imageryOptions = ref([
  {
    name: "OpenStreetMap",
    type: "osm",
    provider: null,
    loading: false,
  },
  {
    name: "天地图影像",
    type: "tdt-image",
    provider: null,
    loading: false,
  },
  {
    name: "天地图矢量",
    type: "tdt-vector",
    provider: null,
    loading: false,
  },
  {
    name: "离线影像地图",
    type: "offline-image",
    url: "https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer/tile/{z}/{y}/{x}",
    provider: null,
    loading: false,
  },
]);

// 方法：切换底图图层
function switchLayer(option) {
  const viewer = injectedViewerRef && injectedViewerRef.value;
  if (!viewer) return;

  // 1) 若已选中图层，则先移除
  if (currentLayer.value) {
    try {
      viewer.imageryLayers.remove(currentLayer.value);
    } catch (e) {
      console.warn("移除图层失败：", e);
    }
  }

  // 2) 若目标图层已创建，则直接添加；否则先创建
  if (!option.provider) {
    option.loading = true;
    createImageryProvider(option)
      .then((provider) => {
        if (provider) {
          option.provider = provider;
          currentLayer.value = viewer.imageryLayers.addImageryProvider(provider);
        }
      })
      .catch((e) => {
        console.error("创建图层失败：", e);
      })
      .finally(() => {
        option.loading = false;
      });
  } else {
    // 直接添加已创建的图层
    currentLayer.value = viewer.imageryLayers.addImageryProvider(option.provider);
  }
}

// 方法：根据选项创建对应的 imageryProvider
async function createImageryProvider(option) {
  switch (option.type) {
    case "osm":
      return new Cesium.OpenStreetMapImageryProvider({
        url: "https://tile.openstreetmap.org/",
      });

    case "tdt-image":
      // 天地图影像（经纬度坐标系）
      return new Cesium.WebMapTileServiceImageryProvider({
        url: "https://t0.tianditu.gov.cn/img_w/wmts?tk=9c117b5778524c413c7834670243943b",
        layer: "img",
        style: "default",
        format: "tiles",
        tileMatrixSetID: "w",
        maximumLevel: 18,
      });

    case "tdt-vector":
      // 天地图矢量（经纬度坐标系）
      return new Cesium.WebMapTileServiceImageryProvider({
        url: "https://t0.tianditu.gov.cn/vec_w/wmts?tk=9c117b5778524c413c7834670243943b",
        layer: "vec",
        style: "default",
        format: "tiles",
        tileMatrixSetID: "w",
        maximumLevel: 18,
      });

    case "offline-image":
      // 离线影像地图（ArcGIS服务）
      return new Cesium.UrlTemplateImageryProvider({
        url: option.url,
      });

    default:
      console.warn("未知的底图类型：", option.type);
      return null;
  }
}

// 生命周期：组件挂载后，默认选中第一个图层
onMounted(() => {
  // 等待父组件创建 viewer 后再进行图层切换
  const viewer = injectedViewerRef && injectedViewerRef.value;
  if (!viewer) {
    const stop = watch(
      () => injectedViewerRef.value,
      (v) => {
        if (v) {
          // 默认选中第一个图层（OpenStreetMap）
          switchLayer(imageryOptions.value[0]);
          stop();
        }
      }
    );
  } else {
    // 默认选中第一个图层（OpenStreetMap）
    switchLayer(imageryOptions.value[0]);
  }
});
</script>

<style scoped>
.imagery-control {
  position: absolute;
  left: 12px;
  bottom: 12px;
  z-index: 20;
}
</style>


